package dao;

import java.util.ArrayList;

import model.Location;
import model.Process;
import model.ProductType;
import model.Stack;

public class Dao {

    private static Dao dao = null;

    private final ArrayList<ProductType> productTypes;
    private final ArrayList<Process> processes;
    private final ArrayList<Stack> stacks;
    private final ArrayList<Location> locations;
    private final ArrayList<Stack> finished;
    private final ArrayList<Stack> wastes;

    private int stackWidth;
    private int stackHeight;

    // Constructor is private because we are using Singleton pattern
    private Dao() {
	productTypes = new ArrayList<ProductType>();
	processes = new ArrayList<Process>();
	stacks = new ArrayList<Stack>();
	locations = new ArrayList<Location>();
	stackWidth = 5;
	stackHeight = 5;
	wastes = new ArrayList<Stack>();
	finished = new ArrayList<Stack>();
    }

    public static Dao getInstance() {
	if (dao == null) {
	    dao = new Dao();
	}
	return dao;
    }

    public int getStackWidth() {
	return stackWidth;
    }

    public void setStackWidth(int stackWidth) {
	this.stackWidth = stackWidth;
    }

    public int getStackHeight() {
	return stackHeight;
    }

    public void setStackHeight(int stackHeight) {
	this.stackHeight = stackHeight;
    }

    public ArrayList<ProductType> getProductTypes() {
	return new ArrayList<ProductType>(productTypes);
    }

    public ArrayList<Process> getProcesses() {
	return new ArrayList<Process>(processes);
    }

    public ArrayList<Stack> getStacks() {
	return new ArrayList<Stack>(stacks);
    }

    public ArrayList<Location> getLocations() {
	return new ArrayList<Location>(locations);
    }

    public ArrayList<Stack> getFinished() {
	return new ArrayList<Stack>(finished);
    }

    public ArrayList<Stack> getWastes() {
	return new ArrayList<Stack>(wastes);
    }

    public Object store(Object obj) {
	if (obj instanceof Stack) {
	    if (stacks.contains(obj))
		return obj;

	    stacks.add((Stack) obj);
	} else if (obj instanceof Process) {
	    if (processes.contains(obj))
		return obj;

	    processes.add((Process) obj);
	} else if (obj instanceof ProductType) {
	    if (productTypes.contains(obj))
		return obj;

	    productTypes.add((ProductType) obj);
	} else if (obj instanceof Location) {
	    if (locations.contains(obj))
		return obj;
	    locations.add((Location) obj);

	}

	return obj;

    }

    public void remove(Object obj) {
		if (obj instanceof Stack) {
		    if (stacks.contains(obj))
		    	stacks.remove(obj);
		}
		else if (obj instanceof ProductType) {
			if (productTypes.contains(obj))
				productTypes.remove(obj);
		}
		else if (obj instanceof Process) {
			if (processes.contains(obj))
				processes.remove(obj);
		}
    }

    public void putInWastes(Stack stack) {
	if (!wastes.contains(stack)) {
	    stack.removeLocation();
	    stacks.remove(stack);
	    wastes.add(stack);
	}
    }

    public void putInFinished(Stack stack) {
	if (!finished.contains(stack)) {
	    stack.removeLocation();
	    stacks.remove(stack);
	    finished.add(stack);
	}
    }
}
